package com.wdh.networklibrary.base;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public abstract class BaseLazyFragment extends Fragment {
    // 布局成功已经加载的标志位
    private boolean isViewLoaded = false;
    // 数据已经加载的标志位
    private boolean isDataLoaded = false;
    // contentView
    private View contentView;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getLifecycle().addObserver(new Java8Observer());
        initConfiguration(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        this.contentView = inflater.inflate(getContentLayout(), container, false);
        this.isViewLoaded = true;
        return contentView;
    }

    @Override
    public void onStart() {
        super.onStart();
        if (getUserVisibleHint() &&isViewLoaded) {
            if (!isDataLoaded) {
                initView(getContentView());
                this.isDataLoaded = loadData();
            }
        }
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (getUserVisibleHint() && isViewLoaded) {
            if (!isDataLoaded) {
                initView(getContentView());
                this.isDataLoaded = loadData();
            }
        }
    }

    @Override
    public void onDestroyView() {
        // 若View被销毁了，则需要重新创建View，此时应该把标志位复原
        this.isViewLoaded = false;
        isDataLoaded = false;
        super.onDestroyView();
    }

    /**
     * 用于子类得到contentView
     *
     * @return contentView
     */
    public View getContentView() {
        return this.contentView;
    }

    /**
     * 该方法在Fragment的OnCreate方法被执行时调用
     * 主要用于初始化其他模块传递到fragment中的数据
     * 该方法可以选择性地去实现
     *
     * @param bundle 数据包
     */
    protected void initConfiguration(Bundle bundle) {
    }

    /**
     * 在加载布局前调用，用于获取布局文件资源
     *
     * @return 返回一个布局文件的layout资源
     */
    protected abstract int getContentLayout();

    /**
     * 实现View初始化的懒加载
     * 该方法会在OnStart方法执行时调用，或者是在对用户可见时调用，但无论是哪个地方调用，都只会执行一次
     * 在该方法中可以实现findViewById、view的事件初始化等
     * 在OnStart后：若是在OnStart时被调用，则要满足两个条件，1：当前的fragment对用户是可见的；2、布局文件已经
     * 在对用户可见时：若是OnStart是没有调用，而是在对用户可见时被调用，则说明在OnStart方法执行时，当前的fragment对用户不可见
     *
     * @param contentView contentView
     */
    protected void initView(View contentView) {
    }

    /**
     * 实现数据的懒加载
     * 该方法会在OnStart方法执行时调用，或者是在对用户可见时调用，但无论是哪个地方调用，都只会执行一次
     * 在OnStart后：若是在OnStart时被调用，则要满足两个条件，1：当前的fragment对用户是可见的；2、布局文件已经
     * 在对用户可见时：若是OnStart是没有调用，而是在对用户可见时被调用，则说明在OnStart方法执行时，当前的fragment对用户不可见
     *
     * @return 返回Boolean类型的值，若为true：说明已经执行了加载数据的操作；若为false：说明未执行加载数据的操作
     */
    protected abstract boolean loadData();

}
